package ch.rmy.android.http_shortcuts.scripting.actions.types

import android.content.Context
import ch.rmy.android.framework.extensions.logInfo
import ch.rmy.android.framework.extensions.truncate
import ch.rmy.android.http_shortcuts.R
import ch.rmy.android.http_shortcuts.data.domains.variables.GlobalVariableRepository
import ch.rmy.android.http_shortcuts.data.domains.variables.VariableKeyOrId
import ch.rmy.android.http_shortcuts.data.enums.VariableType
import ch.rmy.android.http_shortcuts.exceptions.ActionException
import ch.rmy.android.http_shortcuts.scripting.ExecutionContext
import ch.rmy.android.http_shortcuts.widget.VariableWidgetManager
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject

class SetVariableAction
@Inject
constructor(
    @ApplicationContext
    private val context: Context,
    private val globalVariableRepository: GlobalVariableRepository,
    private val variableWidgetManager: VariableWidgetManager,
) : Action<SetVariableAction.Params> {
    override suspend fun Params.execute(executionContext: ExecutionContext) {
        logInfo("Setting variable value (${value.length} characters)")
        executionContext.variableManager.setVariableValueByKeyOrId(variableKeyOrId, value, storeOnly)
        try {
            val variable = globalVariableRepository.getVariableByKeyOrId(variableKeyOrId)
            globalVariableRepository.setVariableValue(variable.id, value.truncate(MAX_VARIABLE_LENGTH))
            if (variable.type == VariableType.CONSTANT) {
                variableWidgetManager.updateWidgets(context, variable.id)
            }
        } catch (_: NoSuchElementException) {
            if (variableKeyOrId.globalVariableId != null) {
                throw ActionException {
                    getString(
                        R.string.error_variable_not_found_write,
                        variableKeyOrId,
                    )
                }
            }
        }
    }

    data class Params(
        val variableKeyOrId: VariableKeyOrId,
        val value: String,
        val storeOnly: Boolean,
    )

    companion object {
        private const val MAX_VARIABLE_LENGTH = 40_000
    }
}
